package config

import (
	"fmt"
	"source-admin-go/pkg/e"

	"github.com/spf13/viper"
)

type MYSQL struct {
	Url      string `mapstructure:"URL"`
	Port     uint   `mapstructure:"PORT"`
	Username string `mapstructure:"USERNAME"`
	Password string `mapqstructure:"PASSWORD"`
	DbName   string `mapqstructure:"DBNAME"`
}

type REDIS struct {
	Addr     string `mapqstructure:"ADDR"`
	Port     uint   `mapqstructure:"PORT"`
	Db       int    `mapqstructure:"DB"`
	Password string `mapqstructure:"PASSWORD"`
}

type DATABASE struct {
	Mysql MYSQL `mapstructure:"DATASOURCE"`
	Redis REDIS `mapstructure:"REDIS"`
}

type RouterConfig struct {
	Url  string `mapstructure:"URL"`
	Port uint   `mapstructure:"PORT"`
}

type SERVICE struct {
	Localhost  RouterConfig `mapstructure:"LOCALHOST"`
	Dev        RouterConfig `mapstructure:"DEV"`
	Production RouterConfig `mapstructure:"PRODUCTION"`
}

type SERVER struct {
	Database DATABASE `mapstructure:"SERVER"`
	Service  SERVICE  `mapstructure:"SERVICE"`
	Env      string   `mapstructure:"ENV"`
}

var Server *SERVER
var filePath = "./src/config/application.yml"
var paramsCheck = []string{
	"SERVER.DATASOURCE.URL",
	"SERVER.DATASOURCE.PORT",
	"SERVER.DATASOURCE.USERNAME",
	"SERVER.DATASOURCE.PASSWORD",
	"SERVER.DATASOURCE.DBNAME",
}

func init() {
	var s SERVER
	WriteYmlFile(&s, paramsCheck)
	Server = &s
}

func WriteYmlFile(cfg *SERVER, paramsString []string) {
	// 设置配置文件信息
	viper.SetConfigType("yml")
	viper.SetConfigFile(filePath)

	// 读取配置文件
	err := viper.ReadInConfig()
	if err != nil {
		str := fmt.Sprintf("Failed to read the configuration file. Exception message is : %v", err)
		e.ErrorLogPrintln(str)
		return
	}

	// 判断key是否存在, 返回true/false
	for _, param := range paramsString {
		if !viper.IsSet(param) {
			message := fmt.Sprintf("Yaml config：【%v parameter missing】", param)
			e.ErrorLogPrintln(message)
		}
	}

	// 将文件内容解析后封装到cfg对象中
	err = viper.Unmarshal(&cfg)
	if err != nil {
		str := fmt.Sprintf("Failed to parse the configuration file with exception message : %v", err)
		e.ErrorLogPrintln(str)
		return
	}
}
